﻿using System;
using System.Collections.Generic;

namespace Bubble
{
    class Field
    {
        public int[,] FieldContent;

        private int[] colDirection = new int[] { -1, 0, 1, 0 };
        private int[] rowDirection = new int[] { 0, -1, 0, 1 };
        public int RowsStart { get; set; }
        public int ColStart { get; set; }
        public bool isEndGame { get; set; }
        private Random next = new Random();

        public Field(int rows, int cols, int setRowStart)
        {
            FieldContent = new int[rows, cols];
            this.RowsStart = setRowStart;
            this.isEndGame = false;
            this.ColStart = 0;
            for (int i = 0; i < 3; i++)
            {
                this.AddNewLine();
            }
        }

        public void AddNewLine()
        {
            int[,] newMatrix = new int[this.FieldContent.GetLength(1), this.FieldContent.GetLength(0)];
            TakeNewSymbol(newMatrix);

            AddNewLineArrey(newMatrix);

            ChekIsItEndOfGame();

        }

        private void ChekIsItEndOfGame()
        {
            for (int i = 0; i < FieldContent.GetLength(1); i++)
            {
                if (this.FieldContent[FieldContent.GetLength(1) - 1, i] != 0)
                {
                    this.isEndGame = true;
                }
            }
        }

        private void AddNewLineArrey(int[,] newMatrix)
        {
            for (int i = 1; i < FieldContent.GetLength(0); i++)
            {
                for (int j = 0; j < FieldContent.GetLength(1); j++)
                {
                    newMatrix[i, j] = this.FieldContent[i - 1, j];
                }
            }
            this.FieldContent = newMatrix;
        }

        private void TakeNewSymbol(int[,] newMatrix)
        {
            for (int i = 0; i < newMatrix.GetLength(0); i++)
            {
                newMatrix[0, i] = next.Next(1, 3);
            }
        }
        public void Print()
        {
            int sratRow = this.RowsStart;
            for (int i = 0; i < this.FieldContent.GetLength(1); i++)
            {
                Console.SetCursorPosition(this.ColStart, sratRow++);
                for (int j = 0; j < this.FieldContent.GetLength(0); j++)
                {
                    if (this.FieldContent[i, j] != 0)
                    {
                        Console.Write(this.FieldContent[i, j]);
                    }
                    else
                    {
                        Console.Write(' ');
                    }
                }
            }
        }

        internal int PutNewSymbol(int col, int symbol)
        {
            for (int i = this.FieldContent.GetLength(1) - 1; i >= 0; i--)
            {
                if (this.FieldContent[i, col] != 0)
                {
                    this.FieldContent[i + 1, col] = symbol;
                    return Points(i + 1, col);
                }
            }
            return 0;
        }

        private int Points(int row, int col)
        {
            int takeHittedPoits = 0;
            if (ChekNeighboars(row, col))
            {
                takeHittedPoits = TakeHittedPoints(row, col, this.FieldContent[row, col]);
                //                takeHittedPoits += ClearAllWithouthNeighboars();
            }
            return takeHittedPoits;
        }

        //private int ClearAllWithouthNeighboars()
        // {
        //     int points = 0;
        //     for (int i = 0; i < this.FieldContent.GetLength(0); i++)
        //     {
        //         for (int j = 0; j < this.FieldContent.GetLength(1); j++)
        //         {
        //             if (FieldContent[i, j] != 0)
        //             {
        //                 int currentCount = 0;
        //                 for (int d = 0; d < rowDirection.Length; d++)
        //                 {
        //                     int newRow = i + rowDirection[d];
        //                     int newCol = j + colDirection[d];
        //                     if (newRow >= 0 &&
        //                         newCol >= 0 &&
        //                         newRow < this.FieldContent.GetLength(0) &&
        //                         newCol < this.FieldContent.GetLength(1))
        //                     {
        //                         if (this.FieldContent[newRow, newCol] == 0)
        //                         {
        //                             currentCount++;
        //                         }
        //                     }
        //                     else
        //                     {
        //                         currentCount++;
        //                     }
        //                                             }
        //                 if (currentCount == 4)
        //                 {
        //                     this.FieldContent[i, j] = 0;
        //                     points++;
        //                 }
        //             }
        //         }
        //     }
        //     return points;
        // }

        private bool ChekNeighboars(int row, int col)
        {
            for (int i = 0; i < rowDirection.Length; i++)
            {
                int newRow = row + this.rowDirection[i];
                int newCol = col + this.colDirection[i];
                if (newRow >= 0 &&
                    newCol >= 0 &&
                    newRow < this.FieldContent.GetLength(0) &&
                    newCol < this.FieldContent.GetLength(1))
                {
                    if (this.FieldContent[newRow, newCol] == this.FieldContent[row, col])
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        private int TakeHittedPoints(int row, int col, int symbol)
        {
            int[] startPoint = new int[] { row, col };
            Queue<int[]> positions = new Queue<int[]>();
            positions.Enqueue(startPoint);
            int points = 0;
            while (positions.Count != 0)
            {
                int[] currentPoint = positions.Dequeue();
                this.FieldContent[currentPoint[0], currentPoint[1]] = 0;
                points++;
                for (int i = 0; i < rowDirection.Length; i++)
                {
                    int[] newRowCol = new int[] { currentPoint[0] + this.rowDirection[i], currentPoint[1] + this.colDirection[i] };
                    if (newRowCol[0] >= 0 &&
                        newRowCol[1] >= 0 &&
                        newRowCol[0] < this.FieldContent.GetLength(0) &&
                        newRowCol[1] < this.FieldContent.GetLength(1))
                    {
                        if (this.FieldContent[newRowCol[0], newRowCol[1]] == symbol)
                        {
                            positions.Enqueue(newRowCol);
                        }
                    }
                }
            }
            return points;

        }
    }
}
